Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DepositContract): Introduce operator pubkey mapping #2089

Closed
wants to merge 3 commits into from

Conversation

sj448
Copy link

@sj448 sj448 commented Oct 22, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced operator management for public keys in the deposit process.
    • Added functionality to register and update operators during deposits.
    • Introduced new methods to retrieve operator information.
  • Bug Fixes

    • Improved error handling for operator-related operations, ensuring correct reverts for unauthorized actions.
  • Documentation

    • Updated documentation to reflect changes in function signatures and new error types related to operator management.

Copy link
Contributor

coderabbitai bot commented Oct 22, 2024

Walkthrough

The changes include enhancements to the DepositContract, IDepositContract, and related test files, focusing on operator management for public keys. A new private mapping, operatorByPubKey, has been introduced to associate public keys with operator addresses. The deposit function has been updated to accept an operator parameter, and a new function, updateOperator, allows changing the operator. Additionally, relevant events and error types have been added to improve functionality and error handling across the contracts and their interfaces.

Changes

File Change Summary
contracts/src/staking/DepositContract.sol - Added private mapping operatorByPubKey.
- Updated deposit function to include address operator.
- Added updateOperator and getOperator functions.
- Emitted OperatorUpdated event.
contracts/src/staking/IDepositContract.sol - Updated deposit function signature.
- Added getOperator function.
- Added OperatorUpdated event and new error types: ZeroOperatorOnFirstDeposit, NotCurrentOperator, ZeroAddress.
contracts/test/staking/DepositContract.t.sol - Added internal variable operator.
- Updated multiple test cases to include operator parameter.
- Added tests for updateOperator functionality.
contracts/test/staking/PermissionedDepositContract.sol - Updated deposit function signature to include address operator.
mod/geth-primitives/pkg/deposit/contract.abigen.go - Updated Deposit function signature.
- Added getOperator and updateOperator functions.
- Updated ABI to include new error types and events.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DepositContract
    participant IDepositContract

    User->>DepositContract: deposit(pubkey, credentials, amount, signature, operator)
    DepositContract->>IDepositContract: validate deposit
    IDepositContract-->>DepositContract: validation result
    DepositContract->>DepositContract: register operator
    DepositContract->>User: emit OperatorUpdated
Loading

🐰 "In the meadow where bunnies play,
New operators join the fray.
With deposits made and roles defined,
A hopping good time, all aligned!
So gather 'round, let's celebrate,
For changes here are truly great!" 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 59d66d9 and 60ccfdd.

📒 Files selected for processing (1)
  • mod/geth-primitives/pkg/deposit/contract.abigen.go (5 hunks)
🧰 Additional context used
🔇 Additional comments (4)
mod/geth-primitives/pkg/deposit/contract.abigen.go (4)

267-297: GetOperator function is correctly implemented

The GetOperator function correctly aligns with the Solidity contract definition, properly retrieving the operator associated with a given public key. The parameter types and return types are appropriate.


538-558: UpdateOperator function added appropriately

The UpdateOperator function has been correctly implemented, matching the Solidity contract. It allows updating the operator for a given public key. The parameter types are accurate, and the function facilitates proper operator management.


766-770: Issue with Pubkey field type remains unresolved

The Pubkey field in the BeaconDepositContractOperatorUpdated struct is still defined as common.Hash. As mentioned previously, since the Solidity event defines pubkey as bytes, which can exceed 32 bytes, using common.Hash (which is fixed at 32 bytes) may lead to truncation of the pubkey data.


454-472: Verify all calls to Deposit include the new operator parameter

The Deposit function signature has been updated to include the operator parameter. Ensure that all invocations of this function throughout the codebase are updated to include the new parameter to prevent compile-time errors or unexpected behavior.

Run the following script to identify calls to Deposit that may need updating:


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Oct 22, 2024

Codecov Report

Attention: Patch coverage is 78.57143% with 3 lines in your changes missing coverage. Please review.

Project coverage is 50.87%. Comparing base (a659c95) to head (59d66d9).

Files with missing lines Patch % Lines
contracts/src/staking/DepositContract.sol 84.61% 2 Missing ⚠️
...racts/test/staking/PermissionedDepositContract.sol 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #2089       +/-   ##
===========================================
+ Coverage   23.50%   50.87%   +27.36%     
===========================================
  Files         356        4      -352     
  Lines       16054       57    -15997     
  Branches       12       16        +4     
===========================================
- Hits         3774       29     -3745     
+ Misses      12115       28    -12087     
+ Partials      165        0      -165     
Files with missing lines Coverage Δ
...racts/test/staking/PermissionedDepositContract.sol 80.00% <0.00%> (-3.34%) ⬇️
contracts/src/staking/DepositContract.sol 83.33% <84.61%> (+9.64%) ⬆️

... and 352 files with indirect coverage changes

@sj448 sj448 self-assigned this Oct 22, 2024
@@ -94,6 +113,31 @@ abstract contract DepositContract is IDepositContract, ERC165 {
}
}

function updateOperator(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neverDefined are we okay with one step operator change process?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two step would be good, on updates only though

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Outside diff range comments (1)
contracts/test/staking/PermissionedDepositContract.sol (1)

Line range hint 1-70: Overall impact is positive. Consider updating documentation.

The changes to the PermissionedDepositContract successfully integrate the new operator functionality from the parent DepositContract while maintaining the existing permission system. The contract's core functionality and inheritance structure remain intact.

Consider updating the contract's documentation (e.g., the @notice comment at the top) to mention the new operator functionality. This will help developers understand the full capabilities of the contract at a glance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between a659c95 and 59d66d9.

📒 Files selected for processing (5)
  • contracts/src/staking/DepositContract.sol (5 hunks)
  • contracts/src/staking/IDepositContract.sol (3 hunks)
  • contracts/test/staking/DepositContract.t.sol (12 hunks)
  • contracts/test/staking/PermissionedDepositContract.sol (2 hunks)
  • mod/geth-primitives/pkg/deposit/contract.abigen.go (5 hunks)
🧰 Additional context used
🔇 Additional comments (13)
contracts/src/staking/IDepositContract.sol (3)

28-36: LGTM! The addition of OperatorUpdated event is well-implemented.

The OperatorUpdated event enhances operator management by providing transparency when an operator is updated. The event parameters are appropriately defined and the use of indexed on pubkey facilitates efficient filtering.


60-68: LGTM! Custom errors improve error handling clarity.

Introducing custom errors like ZeroOperatorOnFirstDeposit(), NotCurrentOperator(), and ZeroAddress() enhances the contract's error handling by providing more specific and gas-efficient revert messages.


73-83: LGTM! The getOperator view function adds valuable functionality.

The getOperator function allows users to retrieve the operator address associated with a given pubkey. The implementation aligns with the interface design, and the documentation is clear and precise.

contracts/src/staking/DepositContract.sol (3)

41-43: Mapping operatorByPubKey correctly associates public keys with operator addresses

The introduction of operatorByPubKey mapping effectively links each public key to its corresponding operator address, which is essential for managing operator assignments.


59-62: Function getOperator correctly retrieves operator addresses

The getOperator function properly exposes the operator address associated with a given public key, allowing external contracts and users to query this information as needed.


92-101: Operator is correctly set during the first deposit

The logic to assign the operator on the first deposit is sound. By checking if the public key is unregistered and ensuring a non-zero operator address, it prevents misuse and maintains data integrity.

contracts/test/staking/DepositContract.t.sol (3)

232-244: Confirm error handling in test_UpdateOperatorNotCurrentOperator.

The test correctly checks for reverts when the caller is not the current operator. Ensure that the NotCurrentOperator error is appropriately emitted when expected.


246-251: Validate zero address check in test_UpdateOperatorZeroAddress.

The test appropriately expects a revert when attempting to set the operator to the zero address, ensuring robustness against invalid inputs.


253-262: test_UpdateOperator correctly verifies operator update functionality.

The test successfully confirms that the operator can be updated and the corresponding event is emitted with correct parameters.

mod/geth-primitives/pkg/deposit/contract.abigen.go (4)

34-35: ABI and Binary Updated to Include New Functions

The ABI and binary have been updated to include the new functions and events, reflecting the changes made to the contract interface.


267-296: Addition of GetOperator Function

The GetOperator function has been correctly added to the contract bindings to retrieve the operator associated with a given public key.


538-557: Addition of UpdateOperator Function

The UpdateOperator function has been successfully added to allow updates to the operator associated with a public key.


454-472: Update Deposit Function Calls to Include New Operator Parameter

The Deposit function signature has been updated to include the operator parameter. Ensure that all invocations of this function across the codebase have been updated to pass the new parameter to prevent any compilation or runtime errors.

Run the following script to find all calls to Deposit and verify they include the new parameter:

Comment on lines +43 to +44
bytes calldata signature,
address operator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

LGTM! Consider enhancing error handling.

The changes to the deposit function are correct and align with the modifications in the parent DepositContract. The new operator parameter is properly included in the function signature and passed to the superclass's deposit function.

Consider adding a check for the operator address to ensure it's not the zero address. This can prevent potential issues with invalid operators. You could add this check right after the existing authorization check:

if (operator == address(0)) revert InvalidOperator();

Don't forget to define the InvalidOperator error at the top of the contract if you decide to implement this suggestion.

Also applies to: 53-55

Comment on lines +96 to +104
* @param operator is the address of the operator.
* @dev emits the Deposit event upon successful deposit.
*/
function deposit(
bytes calldata pubkey,
bytes calldata credentials,
uint64 amount,
bytes calldata signature
bytes calldata signature,
address operator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Some deposit calls are missing the new operator parameter. Please update all implementations and invocations to include it.

🔗 Analysis chain

Verify all implementations and calls to deposit include the new operator parameter.

Adding the operator parameter to the deposit function in IDepositContract is a breaking change. Ensure that all contracts implementing this interface and any external calls have been updated to match the new function signature to prevent integration issues.

Run the following script to identify implementations and calls that may need updating:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all implementations and invocations of `deposit` that may lack the new `operator` parameter.

# Search for `deposit` function definitions excluding the interface file.
rg --glob '!contracts/src/staking/IDepositContract.sol' -t solidity -A 3 'function deposit\('

# Search for invocations of the `deposit` function in Solidity files.
rg -t solidity -A 1 '\.deposit\('

Length of output: 197


Script:

#!/bin/bash
# Description: Find all implementations and invocations of `deposit` that may lack the new `operator` parameter.

# Search for `deposit` function definitions excluding the interface file.
rg --glob '!contracts/src/staking/IDepositContract.sol' -e sol -A 3 'function deposit\('

# Search for invocations of the `deposit` function in Solidity files.
rg -e sol -A 1 '\.deposit\('

Length of output: 232


Script:

#!/bin/bash
# Description: Find all implementations and invocations of `deposit` in Solidity files.

# Define a custom file type for Solidity if not already recognized
rg --type-add 'solidity:*.sol' --type solidity -A 3 'function\s+deposit\s*\(' --glob '!contracts/src/staking/IDepositContract.sol'

# Search for invocations of the `deposit` function in Solidity files
rg --type-add 'solidity:*.sol' --type solidity -A 1 '\.deposit\s*\('

Length of output: 2188

contracts/src/staking/DepositContract.sol Show resolved Hide resolved
Comment on lines +73 to +74
bytes calldata signature,
address operator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Multiple deposit calls missing the operator parameter. Please update all invocations to include the new parameter.

🔗 Analysis chain

Verify all calls to deposit include the new operator parameter

With the addition of the operator parameter to the deposit function, ensure that all existing calls to this function throughout the codebase have been updated accordingly to prevent any breaking changes.

Run the following script to locate all invocations of deposit and check for compliance:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to `deposit` and display their usage.
# Expected Result: All calls should include the new `operator` parameter.

rg -A 2 "deposit\(" --glob "contracts/**/*.sol"

Length of output: 3228


Script:

#!/bin/bash
# Description: Find all calls to `deposit` and count the number of arguments passed.
# Expected Result: All calls should have the expected number of parameters (including `operator`).

rg -n 'deposit\s*\(' --glob 'contracts/**/*.sol' | while read -r line; do
    file=$(echo "$line" | cut -d':' -f1)
    lineno=$(echo "$line" | cut -d':' -f2)
    call=$(echo "$line" | cut -d':' -f3-)
    # Extract the arguments within the parentheses
    args=$(echo "$call" | sed -n 's/.*deposit\s*(\([^)]*\)).*/\1/p')
    # Count the number of arguments by splitting on commas not within parentheses
    arg_count=$(echo "$args" | awk -F',' '{print NF}')
    echo "$file:$lineno: $arg_count arguments"
done

Length of output: 9496

Comment on lines +43 to +44
_create96Byte(),
operator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use pubKey parameter in deposit call for proper fuzz testing.

In testFuzz_DepositsWrongPubKey, the deposit function is called with a hardcoded bytes("wrong_public_key") instead of the pubKey parameter. To effectively fuzz test with various invalid public keys, use the pubKey parameter in the deposit call.

Apply this diff to fix the issue:

 depositContract.deposit(
-    bytes("wrong_public_key"),
+    pubKey,
     STAKING_CREDENTIALS,
     32e9,
     _create96Byte(),
     operator
 );

Committable suggestion was skipped due to low confidence.

Comment on lines +76 to +80
VALIDATOR_PUBKEY,
bytes("wrong_credentials"),
32e9,
_create96Byte(),
operator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use consistent invalid credentials in test_DepositWrongCredentials.

In test_DepositWrongCredentials, consider using a consistent placeholder for invalid credentials similar to other tests. This enhances readability and consistency across tests.

Apply this diff for consistency:

             VALIDATOR_PUBKEY,
-            bytes("wrong_credentials"),
+            INVALID_CREDENTIALS,
             32e9,
             _create96Byte(),
             operator

Where you define INVALID_CREDENTIALS at the beginning of the contract:

+    bytes internal constant INVALID_CREDENTIALS = bytes("wrong_credentials");

Committable suggestion was skipped due to low confidence.

Comment on lines +766 to +770
Pubkey common.Hash
NewOperator common.Address
PreviousOperator common.Address
Raw types.Log // Blockchain specific contextual infos
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect Type for Pubkey in OperatorUpdated Event

The Pubkey field in the BeaconDepositContractOperatorUpdated struct is defined as common.Hash, but the original Solidity event defines pubkey as bytes, which may exceed 32 bytes. Using common.Hash may lead to truncation of pubkey if it is longer than 32 bytes.

To accurately capture the pubkey, consider changing the type to []byte:

-type BeaconDepositContractOperatorUpdated struct {
-	Pubkey           common.Hash
+type BeaconDepositContractOperatorUpdated struct {
+	Pubkey           []byte
 	NewOperator      common.Address
 	PreviousOperator common.Address
 	Raw              types.Log // Blockchain specific contextual infos
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Pubkey common.Hash
NewOperator common.Address
PreviousOperator common.Address
Raw types.Log // Blockchain specific contextual infos
}
type BeaconDepositContractOperatorUpdated struct {
Pubkey []byte
NewOperator common.Address
PreviousOperator common.Address
Raw types.Log // Blockchain specific contextual infos
}

@sj448
Copy link
Author

sj448 commented Oct 22, 2024

Closing this, will moving whole Deposit contract logic to monorepo

@sj448 sj448 closed this Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants